﻿using System;
using System.Collections.Generic;
using System.Text;

using QTOLibrary;

namespace RVBike
{
    class RVMovieController
    {        
        private RVStage _stage = null;
        private RVMovie _movie = null;
        private RVMovieContext _movie_ctx = null;

        private QTMovie _qt_movie = null;
        private AxQTOControlLib.AxQTControl _qt_control = null;

        private float _current_mileage = 0.0f;

        public RVMovieController(RVStage stage, AxQTOControlLib.AxQTControl control)
        {
            if (stage == null)
            {
                throw new System.ArgumentNullException("RVStage");
            }

            if (control == null)
            {
                throw new System.ArgumentNullException("AxQTOControlLib.AxQTControl");
            }

            _stage = stage;
            _qt_control = control;

            if (!LoadMovie(_stage.GetMovie(0)))
            {
                throw new System.Exception(String.Format("No movie objects inside stage : {0}", _stage.Name));
            }
        }

        public void Uninit()
        {
            if (_qt_control != null)
            {
                _qt_control.URL = "";
                //_qt_control.Dispose();
                _qt_control = null;
            }

            if (_movie_ctx != null)
            {
                _movie_ctx.Uninit();
                _movie_ctx = null;
            }
        }

        private bool LoadMovie(RVMovie movie)
        {
            if (movie == null)
            {
                Logger.Instance().Fatal("Movie object cannot be null.");
                return false;
            }

            _qt_control.URL = movie.VideoPath;
            _qt_movie = _qt_control.Movie;

            if (_qt_movie != null)
            {
                _qt_movie.Pause();

                _movie = movie;
                _movie_ctx = new RVMovieContext(_movie);
            }

            return (_qt_movie != null);
        }

        public bool GoMileage(float mileage, bool search = false)
        {
            if (_movie_ctx.GoToMileage(mileage, search))
            {
                _current_mileage = mileage;
                _qt_movie.Time = (int)(_movie_ctx.Time * _qt_movie.TimeScale);

                return true;
            }

            return false;
        }

        public Int32 MovieWidth
        {
            get
            {
                if (_qt_movie == null) new System.NullReferenceException("QT Movie is null");
                return _qt_movie.get_Dimensions().x;
            }
        }

        public Int32 MovieHeight
        {
            get
            {
                if (_qt_movie == null) new System.NullReferenceException("QT Movie is null");
                return _qt_movie.get_Dimensions().y;
            }
        }

        public float MovieDuration
        {
            get
            {
                if (_qt_movie == null) new System.NullReferenceException("QT Movie is null");
                return (float)(_qt_movie.Duration) / _qt_movie.TimeScale;
            }
        }

        public float MovieCurrentTime
        {
            get
            {
                if (_qt_movie == null) new System.NullReferenceException("QT Movie is null");
                return (float)(_qt_movie.Time) / _qt_movie.TimeScale;
            }
        }

        public float MovieCurrentMileage 
        {
            get
            {
                return _current_mileage;
            }
        }

        public float GPSX
        {
            get
            {
                return _movie_ctx.GPSX;
            }
        }

        public float GPSY
        {
            get
            {
                return _movie_ctx.GPSY;
            }
        }

        public float Slope
        {
            get
            {
                return _movie_ctx.Slope;
            }
        }
     
        // for debug only
        public int MovieCurrentFrameIndex
        {
            get
            {
                return _movie_ctx.CurrentFrameIndex;
            }
        }
    }
}
